package com.tanhua.dubbo.api;

import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.dubbo.utils.IdSequeue;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import javax.swing.plaf.nimbus.State;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class PublishApiImpl implements PublishApi {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IdSequeue idSequeue;


    @Override
    public PageResult<Publish> findByRecommend(Long userId, int page, int pagesize) {
        //设置条件
        Query query = new Query(Criteria.where("userId").is(userId).and("publishId").ne(null))
                .with(Sort.by(Sort.Order.desc("created"), Sort.Order.desc("score")))
                .with(PageRequest.of(page - 1, pagesize));
        //查询列表
        List<RecommendQuanZi> quanZiList = mongoTemplate.find(query, RecommendQuanZi.class);
        //查询数量
        long count = mongoTemplate.count(query, RecommendQuanZi.class);
        //把publishId转换成对应的publish
        List<Publish> publishList = new ArrayList<>(quanZiList.size());
        for (RecommendQuanZi quanZi : quanZiList) {
            Publish publish = mongoTemplate.findById(quanZi.getPublishId(), Publish.class);
            publishList.add(publish);
        }
        //计算总页数
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        //封装结果
        return new PageResult<>((int) count, pagesize, pages, page, publishList);
    }

    @Override
    public String save(Publish publish) {
        //把动态存储到动态表quanZi-publish里
        publish.setId(ObjectId.get());
        publish.setPid(idSequeue.getNextId("quanZi_publish"));
        publish.setCreated(System.currentTimeMillis());
        mongoTemplate.save(publish);

        //2. 把动态存储到当前用户的相册表quanzi_album_用户id
        Album album = new Album();
        album.setId(ObjectId.get());
        album.setPublishId(publish.getId());
        album.setCreated(System.currentTimeMillis());
        mongoTemplate.save(album, "quanzi_album_" + publish.getUserId());

        //把动态插入到当前用户好友的时间线里quanzi_timeline_好友id
        Query query = new Query(Criteria.where("userId").is(publish.getUserId()));
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        if (friendList.size() > 0) {
            for (Friend friend : friendList) {
                TimeLine timeLine = new TimeLine();
                timeLine.setId(ObjectId.get());
                timeLine.setPublishId(publish.getId());
                timeLine.setUserId(publish.getUserId());
                timeLine.setCreated(System.currentTimeMillis());
                mongoTemplate.save(timeLine, "quanzi_timeline_" + friend.getFriendId());
            }
        }
        return publish.getId().toHexString();
    }

    @Override
    public PageResult<Publish> findByTimeline(int page, int pagesize, long userId) {
        //查询当前用户的时间线
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .with(PageRequest.of(page - 1, pagesize));
        List<TimeLine> timeLineList = mongoTemplate.find(query, TimeLine.class, "quanzi_timeline_" + userId);
        long count = mongoTemplate.count(query, TimeLine.class, "quanzi_timeline_" + userId);
        //把时间线里的publishId，转换成对于的publish对象
        List<Publish> publishList = new ArrayList<>(timeLineList.size());
        for (TimeLine timeLine : timeLineList) {
            ObjectId publishId = timeLine.getPublishId();
            Publish publish = mongoTemplate.findById(publishId, Publish.class);
            publishList.add(publish);
        }
        //3. 封装分页结果
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        PageResult<Publish> publishPageResult = new PageResult<>((int) count, pagesize, pages, page, publishList);
        log.info(String.valueOf(publishPageResult));
        return publishPageResult;

    }

    @Override
    public PageResult<Publish> findAlbumList(int page, int pagesize, Long userId) {
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .with(PageRequest.of(page-1, pagesize));
        List<Album> list = mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        long count = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);

        List<Publish> publishList=new ArrayList<>(list.size());
        for (Album album : list) {
            Publish publish = mongoTemplate.findById(album.getPublishId(), Publish.class);
            publishList.add(publish);
        }
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult<>((int)count,pagesize,pages,page,publishList);
    }

    @Override
    public Publish findOnePublish(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId),Publish.class);
    }

    @Override
    public Publish findById(String publishId) {
        Query query = new Query(Criteria.where("_id").is(new ObjectId(publishId)));
        return mongoTemplate.findOne(query, Publish.class);
    }

    @Override
    public PageResult<Publish> findPublishList(int page, int pagesize, Long uid, String state) {
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .with(PageRequest.of(page - 1, pagesize));
        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (state != null && !state.equals("")) {
            query.addCriteria(Criteria.where("state").is(state));
        }
        List<Publish> list = mongoTemplate.find(query, Publish.class);
        long count = mongoTemplate.count(query, Publish.class);
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult<>((int)count,pagesize,pages,page,list);
    }

    @Override
    public void saveState(Publish publish) {
        Query query = new Query(Criteria.where("id").is(publish.getId()));
        Update update = new Update().set("state", publish.getState());
        mongoTemplate.updateFirst(query, update, Publish.class);
    }



    @Override
    public List<Publish> findByPids(List<Long> pidList) {
        return mongoTemplate.find(new Query(Criteria.where("pid").in(pidList)),Publish.class);
    }

    @Override
    public PageResult<Publish> findPublishListByState(int page, int pagesize, Long uid, Integer state) {
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .with(PageRequest.of(page-1, pagesize));

        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }

        if (state != null && !"".equals(state)) {
            query.addCriteria(Criteria.where("state").is(state));
        }

        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        long count = mongoTemplate.count(query, Publish.class);

        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult<>((int)count, pagesize, pages, page, publishList);
    }

    @Override
    public void updateState(Publish publish) {
        Query query = new Query(Criteria.where("id").is(publish.getId()));
        Update update = new Update().set("state", publish.getState());
        mongoTemplate.updateFirst(query, update, Publish.class);
    }

    @Override
    public List<Publish> findPublishByPids(List<Long> pidList) {
        Query query = new Query(Criteria.where("pid").in(pidList));
        return mongoTemplate.find(query, Publish.class);
    }
    @Override
    public void updateStates(String publishId, int state) {
        Criteria criteria = Criteria.where("id").is(new ObjectId(publishId));
        mongoTemplate.updateFirst(new Query(criteria), new Update().set("state", state), Publish.class);
    }


}
